package vashion.azeroth.core.manager.item;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;
import org.codehaus.jackson.JsonFactory;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.type.TypeReference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import vashion.azeroth.contant.AzerothConstants;
import vashion.azeroth.contant.ItemErrorEnum;
import vashion.azeroth.core.dao.BaseDao;
import vashion.azeroth.core.item.dao.ItemSkuDao;
import vashion.azeroth.core.item.pojo.ItemDO;
import vashion.azeroth.core.item.pojo.ItemSkuDO;
import vashion.azeroth.core.item.pojo.PropertyValueDO;
import vashion.azeroth.core.manager.forest.BasePropertyValueManager;
import vashion.azeroth.core.manager.impl.BaseManagerImpl;
import vashion.azeroth.core.result.ApiResult;

import java.util.*;

/**
 * Created by tingting on 15/8/31.
 * 商品sku维护
 */
@Service
public class BaseItemSkuManager extends BaseManagerImpl<ItemSkuDO> {

    private final static Logger log = LoggerFactory.getLogger(BaseItemSkuManager.class);

    @Autowired
    private ItemSkuDao skuDao;
    @Autowired
    private BasePropertyValueManager basePropertyValueManager;
    @Autowired
    private ItemWriteManager itemWriteManager;

    @Override
    public BaseDao getDao() {
        return skuDao;
    }

    public ApiResult<Boolean> batchSave(List<ItemSkuDO> skuDOList) {

        //FIXME 因为要获取skuId，所以要采用for循环录入
        try {
            for (ItemSkuDO itemSkuDO : skuDOList) {
                skuDao.save(itemSkuDO);
            }
            return ApiResult.newSuccessResult(true);
        } catch (Exception e) {
            log.error("itemDao.batchSave error, skuDOList=" + skuDOList, e);
            return ApiResult.newErrorResult(ItemErrorEnum.SKU_ERROR.getErrorCode(), ItemErrorEnum.SKU_ERROR.getErrorMessage());
        }
    }

    /**
     * 获取sku详情
     *
     * @param skuIdList
     * @return
     */
    public Map<Long, ItemSkuDO> getSkuDetail(List<Long> skuIdList) {
        List<ItemSkuDO> itemSkuDOList = skuDao.findSkuList(skuIdList);
        return fillSkuDetail(itemSkuDOList);
    }
    
    @Override
    public List<ItemSkuDO> find(ItemSkuDO itemSkuDO) {
        List<ItemSkuDO> itemSkuDOList = super.find(itemSkuDO);
        
        //解析sku详情
        fillSkuDetail(itemSkuDOList);
        return itemSkuDOList;
    }

    private Map<Long, ItemSkuDO> fillSkuDetail(List<ItemSkuDO> itemSkuDOList) {
        Map<Long, ItemSkuDO> resultMap = Maps.newHashMap();
        Set<Long> idSet = new HashSet<Long>();
        for (ItemSkuDO itemSkuDO1 : itemSkuDOList) {
            idSet.addAll(itemSkuDO1.getPropertyValueList());
        }
        ApiResult<List<PropertyValueDO>> valueDOList = basePropertyValueManager.getValueList(Lists.newArrayList(idSet));
        if (!valueDOList.isSuccess()) {
            log.error("item sku value detail is empty, skuList=" + itemSkuDOList);
            return resultMap;
        }

        Map<Long, PropertyValueDO> propertyValueDOMap = Maps.newTreeMap();
        for (PropertyValueDO propertyValueDO : valueDOList.getData()) {
            propertyValueDOMap.put(propertyValueDO.getId(), propertyValueDO);
        }

        for (ItemSkuDO itemSkuDO1 : itemSkuDOList) {
            List<Long> idList = itemSkuDO1.getPropertyValueList();
            Map<Long, PropertyValueDO> innerMap = Maps.newHashMap();
            for (Long id : idList) {
                PropertyValueDO copyDO = new PropertyValueDO();
                PropertyValueDO sourceDO = propertyValueDOMap.get(id);
                if (null != sourceDO) {
                    BeanUtils.copyProperties(sourceDO, copyDO);
                    if (copyDO.getCouldAppendImage() == 1) {
                        copyDO.setSkuImage(itemSkuDO1);
                    }
                    innerMap.put(id, copyDO);
                }
            }
            itemSkuDO1.setPropertyValueDOMap(innerMap);
            List<PropertyValueDO> list = Lists.newArrayList(innerMap.values());
            Collections.sort(list, new Comparator<PropertyValueDO>() {
                public int compare(PropertyValueDO o1, PropertyValueDO o2) {
                    return o1.getPropertyMetaTitle().compareTo(o2.getPropertyMetaTitle());
                }
            });
            itemSkuDO1.setPropertyValueDOList(list);
            resultMap.put(itemSkuDO1.getId(), itemSkuDO1);
        }
        return resultMap;
    }

    /**
     * 批量更新sku信息
     *
     * @param skuDOList
     * @return
     */
    public boolean updateSkuList(List<ItemSkuDO> skuDOList) {

        try {
            for (ItemSkuDO itemSkuDO : skuDOList) {
            	if (0 != itemSkuDO.getId()) {
            		this.update(itemSkuDO);
            	} else if (StringUtils.isNotEmpty(itemSkuDO.getPropertyValueIdArr())) {
            		this.save(itemSkuDO);
            	}
            }
        } catch (Exception e) {
            log.error("update sku error skuDOList=" + skuDOList, e);
        }
        return true;
    }

    /**
     * 是否能卖
     *
     * @param skuId
     * @param saleCount
     * @return
     */
    public boolean canSale(long skuId, int saleCount) {
        ItemSkuDO itemSkuDO = this.get(skuId);
        return itemSkuDO.getStock() >= saleCount;
    }

    /**
     * 增减sku库存
     *
     * @param skuId
     * @param num
     * @param isAdd
     * @return
     */
    public boolean updateItemSkuNum(long skuId, int num, boolean isAdd) {

        ItemSkuDO itemSkuDO = skuDao.get(skuId);
        if (!isAdd && itemSkuDO.getStock() < num) {
            log.error("商品不够卖啦，skuId=" + skuId + ", skuDO=" + itemSkuDO + ", num=" + num);
            return false;
        }

        Map<String, Object> paramMap = new HashMap<String, Object>();
        paramMap.put("skuId", skuId);
        paramMap.put("num", num);
        boolean skuChangeSuccess;
        if (isAdd) {
            skuChangeSuccess = skuDao.addItemSkuNum(paramMap);
        } else {
            skuChangeSuccess = skuDao.reduceItemSkuNum(paramMap);
        }
        if (skuChangeSuccess) {
            //级联更新商品的sku数量、商品销量

            long itemId = itemSkuDO.getItemId();
            ItemSkuDO itemSkudo = new ItemSkuDO();
            itemSkudo.setItemId(itemId);
            itemSkudo.setPageSize(AzerothConstants.Item.MAX_SKU_COUNT);
            List<ItemSkuDO> itemSkuDOList = this.find(itemSkudo);
            int stockCount = 0;
            for (ItemSkuDO itemSkuDO1 : itemSkuDOList) {
                stockCount += itemSkuDO1.getStock();
            }
            return itemWriteManager.processSkuNumChange(itemId, num, stockCount, isAdd);
        } else {
            return false;
        }

    }
    
    /**
     * 处理SKU
     *
     */
    public List<ItemSkuDO> parseSku(String miniSkuList, ItemDO itemDO) {

        List<ItemSkuDO> resultList = Lists.newArrayList();
        if (StringUtils.isEmpty(miniSkuList)) {
            return resultList;
        }

        JsonFactory factory = new JsonFactory();
        ObjectMapper mapper = new ObjectMapper(factory);
        TypeReference<List<HashMap<String, String>>> typeRef
                = new TypeReference<List<HashMap<String, String>>>() {
        };
        List<HashMap<String, String>> jsonList = Lists.newArrayList();
        try {
            jsonList = mapper.readValue(miniSkuList, typeRef);
        } catch (Exception e) {
            log.error("mapper.readValue error miniSkuList=" + miniSkuList, e);
            return resultList;
        }
        itemDO.setStock(0);
        for (HashMap<String, String> map : jsonList) {
            ItemSkuDO itemSkuDO = new ItemSkuDO();
            itemSkuDO.setGmtModified(new Date());
            itemSkuDO.setGmtCreate(new Date());
            itemSkuDO.setStock(NumberUtils.toInt(map.get("stock")));
            itemDO.setStock(new Long(itemDO.getStock() + itemSkuDO.getStock()).intValue());
            itemSkuDO.setPropertyValueIdArr(map.get("propertyValueId"));
            if (!StringUtils.isEmpty(map.get("pic"))){
                itemSkuDO.setPic(map.get("pic"));
            }else {
                itemSkuDO.setPic(itemDO.getPic());
            }
            //设置id等属性
            if (map.containsKey("id")) {
                itemSkuDO.setId(NumberUtils.toLong(map.get("id")));
            }
            itemSkuDO.setItemId(itemDO.getId());
            itemSkuDO.setUserId(itemDO.getUserId());
            itemSkuDO.setItemPic(itemDO.getPic());
            itemSkuDO.setItemPrice(itemDO.getPrice());
            itemSkuDO.setVipPrice(itemDO.getVipPrice());
            itemSkuDO.setItemTitle(itemDO.getTitle());
            itemSkuDO.setCategoryId(itemDO.getCategoryId());

            resultList.add(itemSkuDO);
        }

        return resultList;
    }
    
    public List<ItemSkuDO> parseSku(String miniSkuList) {
    	List<ItemSkuDO> skuList = Lists.newArrayList();
        if (StringUtils.isEmpty(miniSkuList)) {
            return skuList;
        }

        JsonFactory factory = new JsonFactory();
        ObjectMapper mapper = new ObjectMapper(factory);
        TypeReference<List<HashMap<String, String>>> typeRef
                = new TypeReference<List<HashMap<String, String>>>() {
        };
        List<HashMap<String, String>> jsonList = Lists.newArrayList();
        try {
            jsonList = mapper.readValue(miniSkuList, typeRef);
        } catch (Exception e) {
            log.error("mapper.readValue error miniSkuList=" + miniSkuList, e);
            return skuList;
        }
        for (HashMap<String, String> map : jsonList) {
            ItemSkuDO itemSkuDO = new ItemSkuDO();
            itemSkuDO.setStock(NumberUtils.toInt(map.get("stock")));
            itemSkuDO.setId(NumberUtils.toLong(map.get("id")));
            skuList.add(itemSkuDO);
        }

        return skuList;
    }
}
